<html>
    <head>
        <title>杂项</title>
    </head>
    <body>
        <script>
             /*
                        七、操作流 (文件上传、下载)

                                   1、 使用流  Working with Streams

                                             Stream对象本身不可序列化。
                                             
                                             因此，如果你直接使用Stream作为应用程序服务的参数或返回值，你可能会遇到问题。

                                             ABP提供了一种特殊类型，IRemoteStreamContent用于获取或返回应用程序服务中的流。


                                             eg：可用于获取和返回流的应用程序服务接口

                                                    using System;
                                                    using System.Threading.Tasks;
                                                    using Volo.Abp.Application.Services;
                                                    using Volo.Abp.Content;

                                                    namespace MyProject.Test
                                                    {
                                                        public interface ITestAppService : IApplicationService
                                                        {
                                                            Task Upload(Guid id, IRemoteStreamContent streamContent);
                                                            Task<IRemoteStreamContent> Download(Guid id);  // 以返回IRemoteStreamContent下载流

                                                            Task CreateFile(CreateFileInput input);
                                                            Task CreateMultipleFile(CreateMultipleFileInput input);
                                                        }

                                                        // 创建文件输入DTO
                                                        public class CreateFileInput
                                                        {
                                                            public Guid Id { get; set; }

                                                            public IRemoteStreamContent Content { get; set; } // 以IRemoteStreamContent作为文件内容
                                                        }

                                                        // 创建多个文件输入DTO
                                                        public class CreateMultipleFileInput
                                                        {
                                                            public Guid Id { get; set; }

                                                            public IEnumerable<IRemoteStreamContent> Contents { get; set; }
                                                        }
                                                    }


                                            需要配置 "AbpAspNetCoreMvcOptions"将DTO类添加到FormBodyBindingIgnoredTypes
                                            
                                            才能在DTO（Data Transfer Object）中使用IRemoteStreamContent

                                                    Configure<AbpAspNetCoreMvcOptions>(options =>
                                                    {
                                                        options.ConventionalControllers.FormBodyBindingIgnoredTypes.Add(typeof(CreateFileInput));
                                                        options.ConventionalControllers.FormBodyBindingIgnoredTypes.Add(typeof(CreateMultipleFileInput));
                                                    });

                                            eg: 可用于获取和返回流的应用程序服务实现

                                                    using System;
                                                    using System.IO;
                                                    using System.Threading.Tasks;
                                                    using Volo.Abp;
                                                    using Volo.Abp.Application.Services;
                                                    using Volo.Abp.Content;

                                                    namespace MyProject.Test
                                                    {
                                                        public class TestAppService : ApplicationService, ITestAppService
                                                        {
                                                            // 实现文件下载
                                                            public Task<IRemoteStreamContent> Download(Guid id)
                                                            {
                                                                // 使用文件流读取本地文件
                                                                var fs = new FileStream("C:\\Temp\\" + id + ".blob", FileMode.OpenOrCreate);
                                                                return Task.FromResult(
                                                                    (IRemoteStreamContent) new RemoteStreamContent(fs) {
                                                                        ContentType = "application/octet-stream"  // 设置媒体类型
                                                                    }
                                                                );
                                                            }


                                                            // 实现文件上传
                                                            public async Task Upload(Guid id, IRemoteStreamContent streamContent)
                                                            {
                                                                using (var fs = new FileStream("C:\\Temp\\" + id + ".blob", FileMode.Create))
                                                                {
                                                                    await streamContent.GetStream().CopyToAsync(fs); // 新疆接收到的流数据写入本地文件

                                                                    await fs.FlushAsync();
                                                                }
                                                            }

                                                            // 创建文件
                                                            public async Task CreateFileAsync(CreateFileInput input)
                                                            {
                                                                using (var fs = new FileStream("C:\\Temp\\" + input.Id + ".blob", FileMode.Create))
                                                                {
                                                                    await input.Content.GetStream().CopyToAsync(fs);
                                                                    await fs.FlushAsync();
                                                                }
                                                            }


                                                            // 创建多个文件
                                                            public async Task CreateMultipleFileAsync(CreateMultipleFileInput input)
                                                            {
                                                                using (var fs = new FileStream("C:\\Temp\\" + input.Id + ".blob", FileMode.Append))
                                                                {
                                                                    foreach (var content in input.Contents)
                                                                    {
                                                                        await content.GetStream().CopyToAsync(fs);
                                                                    }
                                                                    await fs.FlushAsync();
                                                                }
                                                            }
                                                        }
                                                    }

                                            (IRemoteStreamContent与Auto API Controller和Dynamic C#HTTP Proxy系统兼容。)
                    */
        </script>
    </body>
</html>